// struct Solution {}

// impl Solution {
//   pub fn highest_peak(is_water: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
//     let mut land = is_water.clone();  
//     let h = is_water.len();
//     let w = is_water[0].len();
//     let ih = h as i32;
//     let iw = h as i32;
//     let mut waters = vec![];
//     let calc_dist = |(x1, y1), (x2, y2)| {
//       ((if x1 >= x2 { x1 - x2 } else { x2 - x1}) + (if y1 >= y2 { y1 - y2 } else { y1 + y2 })) as i32
//     };
//     for i in 0..h {
//       for j in 0..w {
//         if is_water[i][j] == 1 {
//           waters.push((i, j));
//         }
//       }
//     }
//     for i in 0..h {
//       for j in 0..w {
//         land[i][j] = waters.iter().map(|(x1, y1)| calc_dist((i, j), (*x1, *y1))).min().unwrap();
//       }
//     }
//     land
//   }
// }

struct Solution {}

impl Solution {
  pub fn highest_peak(is_water: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
    let mut land = is_water.clone();  
    let h = is_water.len();
    let w = is_water[0].len();
    let ih = h as i32;
    let iw = w as i32;
    let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)];
    let valid = |x, y, ox, oy| {
      let rx = x as i32 - ox;
      let ry = y as i32 - oy;
      if rx >= 0 && rx < ih && ry >= 0 && ry < iw {
        Some((rx as usize, ry as usize))
      } else {
        None
      }
    };
    let mut queue = vec![];
    for i in 0..h {
      for j in 0..w {
        if is_water[i][j] == 1 {
          queue.push((i, j));
        }
        land[i][j] -= 1;
      }
    }
    while queue.len() >0 {
      let (x, y) = queue.remove(0);
      for (dx, dy) in directions {
        match valid(x, y, dx, dy) {
          Some((rx, ry)) => {
            if land[rx][ry] == -1 {
              land[rx][ry] = land[x][y] + 1;
              queue.push((rx, ry));
            }
          }
          None => {}
        }
      }
    }
    land
  }
}